﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;

using Game.Common;

namespace Game.Surface
{
    public class PlayerColorUpdater
    {

        public static ImageSource GenerateImage(
            BitmapImage picture,
            GamePlayer player,
            bool showColor)
        {
                
            DrawingVisual v = new DrawingVisual();
            DrawingContext context = v.RenderOpen();
//            context.DrawRectangle(Brushes.Blue, new Pen(), new Rect(0,0,picture.Width,picture.Height));
            Brush brush = new ImageBrush(picture);
            context.DrawRectangle(brush,new Pen(),new Rect(0,0,picture.Width,picture.Height));
            context.Close();
            
            RenderTargetBitmap target = new RenderTargetBitmap(
                (int)picture.Width, (int)picture.Height,
                96,96, PixelFormats.Pbgra32);
            target.Render(v);
            
            int stride = (target.PixelWidth * target.Format.BitsPerPixel + 7) / 8;
            byte[] pixels = new byte[stride * target.PixelHeight];
            target.CopyPixels(pixels, stride, 0);
            
            WriteableBitmap result = new WriteableBitmap(
                (int)picture.Width, (int)picture.Height, 
                96, 96, PixelFormats.Bgra32, null);
            
            int[] output = new int[target.PixelWidth * target.PixelHeight];
            for (int i = 0; i < pixels.Length; i += 4)
            {
                Color c = new Color();
                c.B = pixels[i];
                c.G = pixels[i + 1];
                c.R = pixels[i + 2];
                c.A = pixels[i + 3];

                byte common = (byte)(c.R & c.G & c.B);

                Color newColor = GenerateNewColor(
                    player, showColor, ref c, common);

                pixels[i]     = newColor.B;
                pixels[i + 1] = newColor.G;
                pixels[i + 2] = newColor.R;
                pixels[i + 3] = newColor.A;
            }
            
            var rect = new Int32Rect(0, 0, picture.PixelWidth, picture.PixelHeight);
            result.WritePixels(rect, pixels, stride, 0);

            return result;
        }

        private static Color GenerateNewColor(GamePlayer player, 
                                              bool showColor, 
                                              ref Color c, 
                                              byte common)
        {
            Color newColor = new Color();
            newColor.A = c.A;
            newColor.R = common;
            newColor.G = common;
            newColor.B = common;

            byte red = (byte)(common ^ (byte)c.R);
            byte blue = (byte)(common ^ (byte)c.B);
            byte green = (byte)(common ^ (byte)c.G);

            if (showColor)
            {
                if (red > 0 && green < 50 && blue < 50)
                {
                    Color ownerColor = player.Color;
                    if (ownerColor.R > 0)
                    {
                        newColor.R = ownerColor.R;
                    }
                    if (ownerColor.G > 0)
                    {
                        newColor.G = ownerColor.G;
                    }
                    if (ownerColor.B > 0)
                    {
                        newColor.B = ownerColor.B;
                    }
                }
                else if (red > 0)
                {
                    Color ownerColor = player.Color;
                    newColor = c;
                }
            }

            return newColor;
        }

        private static Color ToColor(int original)
        {
            Color c = new Color();

            c.A = (byte)((original >> 0x18) & 0xff);
            c.R = (byte)((original >> 0x10) & 0xff);
            c.G = (byte)((original >> 0x8) & 0xff);
            c.B = (byte)((original) & 0xff);
            return c;
        }

    }
}
